package com.jinhua.mybatis.util;



import com.jinhua.mybatis.annotation.Id;
import com.jinhua.mybatis.config.MybatisConfig;
import com.jinhua.mybatis.mapper.MybatisBaseMapper;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Sql的增强操作工具
 */
public class MybatisPlus {
	private final String INSERT_SQL = "INSERT IGNORE INTO `%s` (%s) VALUES (%s) ";
	private final String UPDATE_SQL = "UPDATE  `%s` SET %s ";
	private final String SELECT_SQL = "SELECT  %s FROM  `%s`";
	private final String DELETE_SQL = "DELETE FROM  %s %s";
	private final String COUNT_ALIAS = "COUNT";
	private final String EMPTY = "";
	private final String COUNT_SQL = "SELECT COUNT(%s) AS " + COUNT_ALIAS + " FROM %s %s";
	private final String SELECT_ONE_SUFFIX = " LIMIT 1";
	private final Pattern bachUpdatePattern = Pattern.compile("WHERE\\s+(`)?(\\w+)(`)?");
	private final Pattern javaFieldPattern = Pattern.compile("java\\.[a-zA-Z]+\\.[a-zA-Z]+");
	private final Pattern multiInsertPattern = Pattern.compile("(?<=VALUES).*");
	private final String MULTI_INSERT_LINK = ",";
	private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
	private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
	private SqlSessionTemplate sqlSessionTemplate;
	private Logger log= LoggerFactory.getLogger(getClass());

	private Pattern idPattern = Pattern.compile(".*(id).*");
	private Map<String, String> sqlParamsCache = new ConcurrentHashMap<>();


	private MybatisPlus() {
		MybatisConfig.getApplicationContext().getBean(MybatisBaseMapper.class);
		sqlSessionTemplate = MybatisConfig.getApplicationContext().getBean(SqlSessionTemplate.class);

	}

	public static MybatisPlus getInstance() {
		return new MybatisPlus();
	}

	public <T> int update(T t, MybatisPlusBuild buildUtil) {
		int result = 0;

		String sql;
		if (t instanceof List) {
			sql = createBatchUpdateSql((List) t, buildUtil);
		} else {
			sql = createSql(t, UPDATE_SQL);
			String assignmentVal = buildUtil.assignmentBuild();
			//添加赋值函数
			if (!assignmentVal.isEmpty()) {

				if (sql.isEmpty()) {
					sql = String.format(UPDATE_SQL, MybatisPlusUtil.getTableNameByClass(t.getClass()), assignmentVal);
				} else {
					sql += "," + assignmentVal;
				}


			}
		}


		if (sql.isEmpty()) {
			return result;
		}

		return sqlSessionTemplate.update((MybatisBaseMapper.class.getCanonicalName() + ".update").intern()
			, new BaseSqlHelper().setSql(buildUtil == null ? sql : sql + buildUtil.build()));
	}

	public int updateNative(String sql) {
		int result = 0;
		if (sql == null || sql.isEmpty()) {
			return result;
		}
		return sqlSessionTemplate.update((MybatisBaseMapper.class.getCanonicalName() + ".update").intern()
			, new BaseSqlHelper().setSql(sql));
	}

	public <T> int save(T... t) {
		int result = 0;
		String sql = createSql(t, INSERT_SQL);
		if (sql.isEmpty()) {
			return result;
		}

		BaseSqlHelper baseSqlHelper = new BaseSqlHelper().setSql(sql);
		List<BaseSqlHelper> baseSqlHelpers = new LinkedList<>();


		int len;
		if (t[0] instanceof List) {
			len = ((List) t[0]).size();
		} else {
			len = t.length;
		}

		for (int i = 0; i < len; i++) {
			if (i == 0) {
				baseSqlHelpers.add(baseSqlHelper);
			} else {
				baseSqlHelpers.add(new BaseSqlHelper());
			}
		}

		result = sqlSessionTemplate.insert((MybatisBaseMapper.class.getCanonicalName() + ".save").intern()
			, baseSqlHelpers);

		setId(baseSqlHelpers, t);

		return result;


	}

	public int saveNative(String sql) {
		int result = 0;
		if (sql == null || sql.isEmpty()) {
			return result;
		}
		result = sqlSessionTemplate.insert((MybatisBaseMapper.class.getCanonicalName() + ".save").intern()
			, new BaseSqlHelper().setSql(sql));

		return result;

	}

	private <T> void setId(List<BaseSqlHelper> baseSqlHelpers, T... t) {
		try {
			if (baseSqlHelpers == null || baseSqlHelpers.isEmpty()) {
				return;
			}
			int len = t.length;
			T obj;
			Long id;
			Boolean isListFLag = Boolean.FALSE;
			List list = null;
			if (t[0] instanceof List) {
				isListFLag = Boolean.TRUE;
				list = (List) t[0];
				len = list.size();
			}

			for (int i = 0; i < len; i++) {
				if (isListFLag) {
					obj = (T) list.get(i);
				} else {
					obj = t[i];
				}

				id = baseSqlHelpers.get(i).getId();

				List<Field> allFields = MybatisPlusUtil.getAllFields(obj.getClass());
				String idFieldName = "";
				for (Field field : allFields) {
					Id idField = field.getAnnotation(Id.class);
					if (idField != null) {
						field.setAccessible(Boolean.TRUE);

						if (field.getType() != Long.class) {
							field.set(obj, Math.toIntExact(id));
						} else {
							field.set(obj, id);
						}
						//恢复id 防止重复设置
						idFieldName = "";

						break;
					}
					if (idPattern.matcher(field.getName().toLowerCase()).matches() && field.getType() != String.class) {
						idFieldName = field.getName();
					}
				}

				if (!idFieldName.isEmpty()) {
					Field field = obj.getClass().getDeclaredField(idFieldName);
					field.setAccessible(Boolean.TRUE);

					if (field.getType() != Long.class) {
						field.set(obj, Math.toIntExact(id));
					} else {
						field.set(obj, id);
					}
				}
			}

		} catch (Exception e) {
			log.warn("Obj={} setId fail", t, e);
		}

	}

	/**
	 * 追加创建的sql
	 *
	 * @param sqlType       sql类型
	 * @param totalSqlBuild 总的sqlbuild
	 * @param obj           被追加的实体
	 * @param k             索引
	 */
	private void appendCreateSql(String sqlType, StringBuilder totalSqlBuild, Object obj, int k) {
		String tmpVal;
		tmpVal = createSql(obj, sqlType);
		if (k == 0) {
			totalSqlBuild.append(tmpVal);
		} else {
			totalSqlBuild.append(MULTI_INSERT_LINK);
			Matcher matcher = multiInsertPattern.matcher(tmpVal);
			if (matcher.find()) {
				totalSqlBuild.append(matcher.group());
			} else {
				totalSqlBuild.append(tmpVal);
			}


		}
	}

	/**
	 * 获取日期的字符串形式
	 *
	 * @param date 日期
	 * @return
	 */
	private String getDateStr(Object date) {
		String result;
		if (date instanceof Date) {


			result = dateTimeFormatter.format(LocalDateTime.ofInstant(((Date) date).toInstant(), ZoneId.systemDefault()));
		} else if (date instanceof LocalDateTime) {
			result = dateTimeFormatter.format((LocalDateTime) date);

		} else if (date instanceof LocalDate) {
			result = dateFormatter.format((LocalDate) date);

		} else if (date instanceof LocalTime) {
			result = timeFormatter.format((LocalTime) date);

		} else {
			result = "";

		}
		return result;

	}

	/**
	 * 删除 禁止了全表删除 删除必须带条件
	 *
	 * @param buildUtil
	 * @return
	 */
	public int delete(MybatisPlusBuild buildUtil) {
		int result = 0;

		if (buildUtil == null) {

			return result;
		}
		return sqlSessionTemplate.delete((MybatisBaseMapper.class.getCanonicalName() + ".delete").intern()
			, new BaseSqlHelper().setSql(String.format(DELETE_SQL, MybatisPlusUtil.getTableNameByClass(buildUtil.getBuildClass()), buildUtil.build())));

	}

	public int deleteNative(String sql) {
		int result = 0;

		if (sql == null || sql.isEmpty()) {

			return result;
		}

		return sqlSessionTemplate.delete((MybatisBaseMapper.class.getCanonicalName() + ".delete").intern()
			, new BaseSqlHelper().setSql(sql));

	}

	/**
	 * 查询
	 *
	 * @param buildUtil
	 * @return
	 */
	public long count(MybatisPlusBuild buildUtil) {
		long result = 0L;

		if (buildUtil == null) {

			return result;
		}
		Map resultMap = sqlSessionTemplate.selectOne((MybatisBaseMapper.class.getCanonicalName() + "." +
				(buildUtil.isCached() ? "selectOneByCache" : "selectOne")).intern()
			, new BaseSqlHelper().setSql(String.format(COUNT_SQL, buildUtil.getCountColumn(),
				MybatisPlusUtil.getTableNameByClass(buildUtil.getBuildClass()), buildUtil.build())));


		if (resultMap != null && !resultMap.isEmpty()) {
			result = (long) resultMap.get(COUNT_ALIAS);
		}

		return result;


	}

	public long countNative(String sql) {
		long result = 0L;

		if (sql == null || sql.isEmpty()) {

			return result;
		}
		Map resultMap = sqlSessionTemplate.selectOne((MybatisBaseMapper.class.getCanonicalName() + ".selectOne").intern()
			, new BaseSqlHelper().setSql(sql));

		if (!resultMap.isEmpty()) {
			result = (long) resultMap.values().iterator().next();

		}

		return result;


	}

	public <T> List<T> findAll(T t, MybatisPlusBuild buildUtil) {

		String sql = getOrSetSql(EMPTY);

		if (sql.isEmpty()) {
			sql = createSql(t, SELECT_SQL);
		}

		if (sql.isEmpty()) {
			return null;
		}

		getOrSetSql(sql);

		if (buildUtil == null) {
			buildUtil = new MybatisPlusBuild(t.getClass());
		}

		List<Map> resultList = sqlSessionTemplate.selectList((MybatisBaseMapper.class.getCanonicalName() + "." +
				(buildUtil.isCached() ? "selectAllByCache" : "selectAll")).intern(),
			new BaseSqlHelper().setSql(buildUtil.getSumSql(sql) + buildUtil.build()));


		List<T> lists = new LinkedList<>();

		if (resultList != null && !resultList.isEmpty()) {

			for (Map map : resultList) {
				lists.add(convertMap2Obj(t, map, Boolean.FALSE));
			}

		}
		return lists;
	}

	public <T> List<T> findAllNative(T t, String sql) {

		if (sql == null || sql.isEmpty()) {
			return null;
		}


		List<Map> resultList = sqlSessionTemplate.selectList((MybatisBaseMapper.class.getCanonicalName() + ".selectAll").intern(),
			new BaseSqlHelper().setSql(sql));

		List<T> lists = new LinkedList<>();

		if (resultList != null && !resultList.isEmpty()) {

			for (Map map : resultList) {
				lists.add(convertMap2Obj(t, map, Boolean.TRUE));
			}

		}


		return lists;
	}

	public <T> T findOne(T t, MybatisPlusBuild buildUtil) {

		String sql = getOrSetSql(EMPTY);

		if (sql.isEmpty()) {
			sql = createSql(t, SELECT_SQL);
		}

		if (sql.isEmpty()) {
			return null;
		}

		getOrSetSql(sql);


		if (buildUtil == null) {
			buildUtil = new MybatisPlusBuild(t.getClass());
		}
		buildUtil.link(SELECT_ONE_SUFFIX);


		Map resultMap = sqlSessionTemplate.selectOne((MybatisBaseMapper.class.getCanonicalName() + "." +
				(buildUtil.isCached() ? "selectOneByCache" : "selectOne")).intern(),
			new BaseSqlHelper().setSql(buildUtil.getSumSql(sql) + buildUtil.build()));


		if (resultMap != null && !resultMap.isEmpty()) {
			t = convertMap2Obj(t, resultMap, Boolean.FALSE);
		} else {
			t = null;
		}
		return t;
	}

	public <T> T findOneNative(T t, String sql) {
		if (sql == null || sql.isEmpty()) {
			return null;
		}


		Map resultMap = sqlSessionTemplate.selectOne((MybatisBaseMapper.class.getCanonicalName() + ".selectOne").intern(),
			new BaseSqlHelper().setSql(sql));


		if (resultMap != null && !resultMap.isEmpty()) {
			t = convertMap2Obj(t, resultMap, Boolean.TRUE);
		} else {
			t = null;
		}
		return t;
	}

	/**
	 * 创建批量更新的sql
	 *
	 * @param list
	 * @param buildUtil
	 * @return
	 */
	private String createBatchUpdateSql(List list, MybatisPlusBuild buildUtil) {

		String bachUpdateSql = "";
		if (list == null || list.isEmpty()) {
			return bachUpdateSql;
		}

		Class<?> superClass = list.get(0).getClass();

		//查找出需要批量更新的字段
		Matcher matcher = bachUpdatePattern.matcher(buildUtil.build());

		String batchField;
		if (matcher.find()) {
			batchField = matcher.group(2);
		} else {
			log.warn("update className ={} not find conditional ", superClass.getCanonicalName());
			return bachUpdateSql;
		}


		List<Field> fields = MybatisPlusUtil.getAllFields(superClass);

		if (fields == null || fields.isEmpty()) {
			return bachUpdateSql;
		}

		//获取所有属性的集合
		Map<String, Field> allFieldMap = new HashMap();

		//存储对应的field的列表名称是否是字符串类型
		Map<String, Boolean> allColumnIsStringMap = new HashMap<>();
		//存储对应的field的列表名称是否是日期类型
		Map<String, Boolean> allColumnIsDateMap = new HashMap<>();

		Field batchUpdateField = null;

		String columnName;
		for (Field field : fields) {

			columnName = MybatisPlusUtil.field2ColumnName(field);

			//排出一些被过滤的名字
			if (columnName.isEmpty()) {
				continue;
			}

			//过滤自己
			if (batchField.equals(columnName)) {
				//获取需要更新字段的属性，用作反射
				batchUpdateField = field;
				continue;
			}
			allColumnIsStringMap.put(columnName, isStrField(field));
			allColumnIsDateMap.put(columnName, isDateField(field));

			//属性变成可读
			field.setAccessible(true);

			allFieldMap.put(columnName, field);

		}


		if (batchUpdateField == null) {
			log.warn("className={} batchUpdate sql not support has not properties={}", superClass.getCanonicalName(), batchField);
			return bachUpdateSql;
		}

		String tableName = MybatisPlusUtil.getTableNameByClass(superClass);


		StringBuilder updateSqlBuild = new StringBuilder();
		StringBuilder tmpUpdateSqlBuild;
		StringBuilder tmpUpdateSqlMiddleBuild;

		//获取属性
		batchUpdateField.setAccessible(true);

		for (Map.Entry<String, Field> entry : allFieldMap.entrySet()) {

			tmpUpdateSqlBuild = new StringBuilder();
			tmpUpdateSqlBuild.append(entry.getKey());
			tmpUpdateSqlBuild.append("=  CASE ");
			tmpUpdateSqlBuild.append(batchField);
			tmpUpdateSqlMiddleBuild = new StringBuilder();

			for (Object obj : list) {

				try {
					Object batchFieldInvoke = batchUpdateField.get(obj);

					//没有条件无需组装
					if (batchFieldInvoke == null) {
						continue;
					}

					Object invoke = entry.getValue().get(obj);

					if (invoke != null) {

						if (tmpUpdateSqlMiddleBuild.toString().contains(batchFieldInvoke.toString())) {
//						//目前应该不需要过滤相同的值
//                            log.warn("properties= [{}] is setting current val = [{}] deprecated", entry.getKey(), invoke);
//                            continue;
						}

						tmpUpdateSqlMiddleBuild.append(" WHEN ");
						String batchUpdateDateStrVal = getDateStr(batchFieldInvoke);
						if (batchUpdateDateStrVal.isEmpty()) {
							tmpUpdateSqlMiddleBuild.append(batchFieldInvoke);
						} else {
							tmpUpdateSqlMiddleBuild.append("'");
							tmpUpdateSqlMiddleBuild.append(batchUpdateDateStrVal);
							tmpUpdateSqlMiddleBuild.append("'");
						}

						tmpUpdateSqlMiddleBuild.append(" THEN ");

						//字符串进行添加字符串操作
						if (allColumnIsStringMap.getOrDefault(entry.getKey(), Boolean.FALSE)) {
							tmpUpdateSqlMiddleBuild.append("'");

							tmpUpdateSqlMiddleBuild.append(invoke);
							tmpUpdateSqlMiddleBuild.append("'");
							//字符串进行添加日期操作
						} else if (allColumnIsDateMap.getOrDefault(entry.getKey(), Boolean.FALSE)) {
							tmpUpdateSqlMiddleBuild.append("'");
							tmpUpdateSqlMiddleBuild.append(getDateStr(invoke));
							tmpUpdateSqlMiddleBuild.append("'");

						} else {
							tmpUpdateSqlMiddleBuild.append(invoke);
						}

					}
				} catch (IllegalAccessException e) {
					continue;
				}


			}
			if (tmpUpdateSqlMiddleBuild.length() != 0) {
				if (updateSqlBuild.length() > 1) {
					updateSqlBuild.append(",");
				}
				updateSqlBuild.append(tmpUpdateSqlBuild.toString());
				updateSqlBuild.append(tmpUpdateSqlMiddleBuild);
				updateSqlBuild.append(" END ");
			}


		}

		bachUpdateSql = String.format(UPDATE_SQL, tableName, updateSqlBuild);

		return bachUpdateSql;
	}


	/**
	 * 获取和插入sql
	 *
	 * @param sql 缓存sql
	 * @return
	 */
	private String getOrSetSql(String sql) {


		StackTraceElement[] allStacks = Thread.currentThread().getStackTrace();


		if (allStacks.length < 3) {
			log.warn("current method  has no super");
			return EMPTY;
		}

		String superFeature = allStacks[3].toString();

		if (sql == null || sql.isEmpty()) {
			return sqlParamsCache.getOrDefault(superFeature, EMPTY);

		} else {

			return sqlParamsCache.put(superFeature, sql);

		}

	}

	/**
	 * 创建sql
	 *
	 * @param t       实体类
	 * @param sqlType sql的类型
	 * @return
	 */

	private <T> String createSql(T t, String sqlType) {
		String sql = "";
		try {

			Class<?> superClass = t.getClass();

			if (sqlType.equals(INSERT_SQL) && superClass.isArray()) {

				//多值插入
				Object[] objArr = (Object[]) t;

				Object firstValFlag = objArr[0];


				StringBuilder totalSqlBuild = new StringBuilder();

				if (objArr.length == 1 && firstValFlag instanceof List) {

					List list = (List) firstValFlag;


					int totalLen = list.size();

					for (int k = 0; k < totalLen; k++) {
						appendCreateSql(sqlType, totalSqlBuild, list.get(k), k);

					}

				} else {
					int totalLen = objArr.length;
					for (int k = 0; k < totalLen; k++) {

						appendCreateSql(sqlType, totalSqlBuild, objArr[k], k);
					}


				}

				sql = totalSqlBuild.toString();
				return sql;

			}


			StringBuilder columnBuild = new StringBuilder();
			StringBuilder valueBuild = new StringBuilder();

			List<Field> fields = MybatisPlusUtil.getAllFields(superClass);
			if (fields != null && !fields.isEmpty()) {
				linkValidField(fields, sqlType, columnBuild, valueBuild, t);
			}

			if (sqlType.equals(SELECT_SQL) && columnBuild.length() == 0) {

				//重新赋值全部查询

				fields = MybatisPlusUtil.getAllFields(superClass);
				if (fields != null && !fields.isEmpty()) {
					linkAllField(fields, columnBuild, sqlType);
				}


			}


			String tableName = MybatisPlusUtil.getTableNameByClass(superClass);


			if (sqlType.equals(INSERT_SQL)) {

				if (columnBuild.length() == 0 || valueBuild.length() == 0) {
					return sql;
				}

				sql = String.format(sqlType, tableName, columnBuild.toString(), valueBuild.toString());

			} else if (sqlType.equals(UPDATE_SQL)) {

				if (columnBuild.length() == 0) {
					return sql;
				}

				sql = String.format(sqlType, tableName, columnBuild.toString());

			} else if (sqlType.equals(SELECT_SQL)) {

				sql = String.format(sqlType, columnBuild.toString(), tableName);


			}


		} catch (IllegalAccessException e) {
			log.error("sql 保存失败", e);
		}

		return sql;


	}


	/**
	 * /**
	 * 连接所有的字段
	 *
	 * @param fields      字段类型
	 * @param sqlType     sql的类型
	 * @param columnBuild 列表的build
	 */
	private void linkAllField(List<Field> fields, StringBuilder columnBuild, String sqlType) {

		for (Field field : fields) {
			//进行其他词语的过滤

			boolean isJavaFieldMatch = !(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers()))
				&& javaFieldPattern.matcher(field.getGenericType().getTypeName()).matches();

			if (!isJavaFieldMatch) {
				continue;
			}

			String columnName = MybatisPlusUtil.field2ColumnName(field);

			if (columnName.isEmpty()) {
				continue;
			}

			if (sqlType.equals(SELECT_SQL)) {
				if (columnBuild.length() > 0) {
					columnBuild.append(",");

				}
				linkColumnNameAndFieldName(columnBuild, field.getName(), columnName);
			}

		}

	}


	/**
	 * 连接列名和字段名
	 *
	 * @param columnBuild 列表的build
	 * @param fieldName   字段名
	 * @param columnName  列表名
	 */
	private void linkColumnNameAndFieldName(StringBuilder columnBuild, String fieldName, String columnName) {

		columnBuild.append("`");
		columnBuild.append(columnName);
		columnBuild.append("` AS ");
		columnBuild.append(fieldName);

	}


	/**
	 * 连接有效的字段
	 *
	 * @param fields      字段类型
	 * @param sqlType     sql的类型
	 * @param columnBuild 列表的build
	 * @param valueBuild  有效值得build
	 * @param t           实体类
	 */
	private <T> void linkValidField(List<Field> fields, String sqlType, StringBuilder columnBuild,
									StringBuilder valueBuild, T t) throws IllegalAccessException {

		for (Field field : fields) {

			field.setAccessible(true);

			Object invoke = field.get(t);
			if (invoke != null) {
				String columnName = MybatisPlusUtil.field2ColumnName(field);

				if (columnName.isEmpty()) {
					continue;
				}

				if (columnBuild.length() > 0) {
					columnBuild.append(",");

				}


				if (sqlType.equals(INSERT_SQL)) {


					if (valueBuild.length() > 0) {
						valueBuild.append(",");

					}
					columnBuild.append("`");
					columnBuild.append(columnName);
					columnBuild.append("`");

					if (isStrField(field)) {

						contactStr(valueBuild, invoke);
					} else if (isDateField(field)) {
						contactStr(valueBuild, getDateStr(invoke));
					} else {

						valueBuild.append(invoke);
					}

				} else if (sqlType.equals(UPDATE_SQL)) {
					columnBuild.append("`");
					columnBuild.append(columnName);
					columnBuild.append("`=");

					if (isStrField(field)) {

						contactStr(columnBuild, invoke);
					} else if (isDateField(field)) {
						contactStr(columnBuild, getDateStr(invoke));
					} else {

						columnBuild.append(invoke);
					}

				} else if (sqlType.equals(SELECT_SQL)) {
					linkColumnNameAndFieldName(columnBuild, field.getName(), columnName);

				}
			}
		}


	}

	private boolean isStrField(Field field) {
		return field.getType() == String.class;
	}

	private boolean isDateField(Field field) {
		return field.getType() == LocalTime.class || field.getType() == LocalDate.class || field.getType() == LocalDateTime.class || field.getType() == Timestamp.class
			|| field.getType() == Date.class || field.getType() == java.sql.Date.class;
	}

	/**
	 * 连接字符串
	 *
	 * @param builder 连接的build
	 * @param invoke  连接的值
	 */
	private void contactStr(StringBuilder builder, Object invoke) {
		builder.append("'");
		builder.append(invoke);
		builder.append("'");

	}


	/**
	 * map转实体类
	 *
	 * @param t              实体类
	 * @param map            map类
	 * @param ignoreCapsLook 忽略大小写
	 * @return
	 */
	private <T> T convertMap2Obj(T t, Map map, Boolean ignoreCapsLook) {
		T obj;
		String propertyName = "";
		try {
			Boolean unAssignFlag = Boolean.TRUE;
			Class<?> superClass = t.getClass();
			obj = (T) superClass.newInstance();

			List<Field> allFields = MybatisPlusUtil.getAllFields(superClass);

			for (Field field : allFields) {
				if (Modifier.isFinal(field.getModifiers()) ||
					Modifier.isFinal(field.getModifiers())) {
					continue;
				}
				propertyName = field.getName();

				Object value = map.get(propertyName);
				if (value == null && ignoreCapsLook) {
					value = map.get(propertyName.toLowerCase());
					if (value == null) {
						value = map.get(propertyName.toUpperCase());
					}
				}
				if (value != null) {
					if (unAssignFlag) {
						unAssignFlag = Boolean.FALSE;
					}

					//修订数据库返回参数类型不匹配问题
					if (value instanceof String) {

						Class filedType = field.getType();

						if (filedType == Long.class) {
							value = Long.parseLong(String.valueOf(value));
						} else if (filedType == Double.class) {
							value = Double.parseDouble(String.valueOf(value));
						} else if (filedType == Integer.class) {
							value = Integer.parseInt(String.valueOf(value));
						} else if (filedType == Float.class) {
							value = Float.parseFloat(String.valueOf(value));
						}

					} else if (value instanceof Date) {
						Class filedType = field.getType();
						ZonedDateTime dateTime = Instant.ofEpochMilli(((Date)value).getTime())
							.atZone(ZoneId.systemDefault());
						if (filedType == LocalDate.class) {
							value = dateTime.toLocalDate();
						} else if (filedType == LocalTime.class) {
							value = dateTime.toLocalTime();
						} else if (filedType == LocalDateTime.class) {
							value = dateTime.toLocalDateTime();
						}
					}


					field.setAccessible(true);
					field.set(obj, value);

				}
			}
			if (unAssignFlag) {
				obj = null;
			}

		} catch (Exception e) {
			log.error(String.format("实体类=%s 属性=%s 读写错误", t.getClass(), propertyName), e);
			obj = null;
		}
		return obj;
	}


}
